package com.jiangyg.mall.product.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jiangyg.mall.core.exception.BusinessException;
import com.jiangyg.mall.db.mybatis.BaseServiceImpl;
import com.jiangyg.mall.core.utils.bean.BeanUtils;
import com.jiangyg.mall.product.constant.ColumnConstant;
import com.jiangyg.mall.product.dto.AttrAttrgroupDTO;
import com.jiangyg.mall.product.dto.AttrDTO;
import com.jiangyg.mall.product.dto.AttrgroupDTO;
import com.jiangyg.mall.product.entity.Attr;
import com.jiangyg.mall.product.entity.AttrAttrgroup;
import com.jiangyg.mall.product.entity.Attrgroup;
import com.jiangyg.mall.product.vo.AttrVO;
import com.jiangyg.mall.product.vo.AttrgroupVO;
import com.jiangyg.mall.product.dao.AttrAttrgroupDao;
import com.jiangyg.mall.product.dao.AttrDao;
import com.jiangyg.mall.product.dao.AttrgroupDao;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AttrgroupServiceImpl extends BaseServiceImpl<AttrgroupDao, Attrgroup> implements AttrgroupService {

    private final AttrDao attrDao;

    private final AttrAttrgroupDao attrAttrgroupDao;

    @Autowired
    public AttrgroupServiceImpl(AttrDao attrDao,
                                AttrgroupDao attrgroupDao,
                                AttrAttrgroupDao attrAttrgroupDao) {
        super(attrgroupDao);
        this.attrDao = attrDao;
        this.attrAttrgroupDao = attrAttrgroupDao;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<AttrgroupVO> selectList(String categoryId) throws Exception {
        final QueryWrapper<Attrgroup> wrapper = new QueryWrapper<>();
        wrapper.eq(ColumnConstant.CATEGORY_ID, categoryId);
        wrapper.orderByAsc(ColumnConstant.SORT);
        return BeanUtils.transformList(this.baseMapper.selectList(wrapper), AttrgroupVO.class);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<AttrgroupVO> listAttachAttr(Long categoryId) throws Exception {
        // 查询分类下所有的属性分组
        final List<Attrgroup> attrgroups;
        {
            final QueryWrapper<Attrgroup> wrapper = new QueryWrapper<>();
            wrapper.eq(ColumnConstant.CATEGORY_ID, categoryId);
            wrapper.orderByAsc(ColumnConstant.SORT);
            attrgroups = this.baseMapper.selectList(wrapper);
            if (CollectionUtils.isEmpty(attrgroups)) {
                return new ArrayList<>();
            }
        }
        // 根据属性分组查询关联表，取出所有的属性列表
        final List<AttrAttrgroup> attrAttrgroups;
        {
            final List<Long> attrgroupIds = attrgroups.stream().map(Attrgroup::getId).collect(Collectors.toList());
            final QueryWrapper<AttrAttrgroup> wrapper = new QueryWrapper<>();
            wrapper.in(ColumnConstant.ATTRGROUP_ID, attrgroupIds);
            wrapper.orderByAsc(ColumnConstant.ATTRGROUP_ID, ColumnConstant.ATTR_SORT);
            attrAttrgroups = this.attrAttrgroupDao.selectList(wrapper);
        }
        // 关联表查询出来的所有属性ID，查询出所有属性详情
        final List<Attr> attrs;
        {
            final List<Long> attrIds = attrAttrgroups.stream().map(AttrAttrgroup::getAttrId).collect(Collectors.toList());
            final QueryWrapper<Attr> wrapper = new QueryWrapper<>();
            wrapper.in(ColumnConstant.ID, attrIds);
            attrs = this.attrDao.selectList(wrapper);
        }
        // TODO 优化
        // 组装数据（此处代码比较变态，层次太多，为效率考虑不想用lambda）
        final List<AttrgroupVO> attrgroupDTOS = BeanUtils.transformList(attrgroups, AttrgroupVO.class);
        for (AttrgroupVO group : attrgroupDTOS) {
            // 创建分组下属性集合
            final List<AttrDTO> attrList = new ArrayList<>();
            // 遍历关联
            final Iterator<AttrAttrgroup> iterator = attrAttrgroups.iterator();
            while (iterator.hasNext()) {
                final AttrAttrgroup relation = iterator.next();
                if (StringUtils.equals(group.getId(), relation.getAttrgroupId().toString())) {
                    final Iterator<Attr> attrIterator = attrs.iterator();
                    while (attrIterator.hasNext()) {
                        final Attr attr = attrIterator.next();
                        if (relation.getAttrId().equals(attr.getId())) {
                            final AttrDTO attrDTO = new AttrDTO();
                            BeanUtils.copyProperties(attrDTO, attr);
                            attrList.add(attrDTO);
                            attrIterator.remove();
                        }
                    }
                    iterator.remove();
                }
            }
            group.setAttrs(attrList);
        }
        return attrgroupDTOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(AttrgroupDTO dto) throws Exception {
        return this.executeSaveOrUpdate(dto) > 0;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public AttrgroupVO selectById(Long attrgroupId) throws Exception {
        return this.executeSelectById(attrgroupId, AttrgroupVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(List<Long> attrgroupIds) {
        return this.baseMapper.deleteBatchIds(attrgroupIds) > 0;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<AttrVO> listRelation(Long attrgroupId) throws Exception {
        final QueryWrapper<Attr> wrapper = new QueryWrapper<>();
        final String inSqlWhere = "select attr_id from mp_attr_attrgroup where attrgroup_id=" + attrgroupId;
        wrapper.inSql(ColumnConstant.ID, inSqlWhere);
        return BeanUtils.transformList(this.attrDao.selectList(wrapper), AttrVO.class);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<AttrVO> listNotRelation(Long categoryId) throws Exception {
        final QueryWrapper<Attr> wrapper = new QueryWrapper<>();
        wrapper.eq(ColumnConstant.CATEGORY_ID, categoryId);
        wrapper.notInSql(ColumnConstant.ID, "select attr_id from mp_attr_attrgroup");
        return BeanUtils.transformList(this.attrDao.selectList(wrapper), AttrVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRelation(AttrAttrgroupDTO dto) throws Exception {
        // 是否已有关系
        final QueryWrapper<AttrAttrgroup> wrapper = new QueryWrapper<>();
        wrapper.eq(ColumnConstant.ATTR_ID, dto.getAttrId());
        wrapper.eq(ColumnConstant.ATTRGROUP_ID, dto.getAttrgroupId());
        final Integer count = this.attrAttrgroupDao.selectCount(wrapper);
        if (count > 0) {
            throw BusinessException.instance("mall.product.attrgroup.save.haveChildren");
        }
        // 新增
        final AttrAttrgroup attrAttrgroup = new AttrAttrgroup();
        BeanUtils.copyProperties(attrAttrgroup, dto);
        return this.attrAttrgroupDao.insert(attrAttrgroup) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRelation(AttrAttrgroupDTO dto) {
        final UpdateWrapper<AttrAttrgroup> wrapper = new UpdateWrapper<>();
        wrapper.eq(ColumnConstant.ATTR_ID, dto.getAttrId());
        wrapper.eq(ColumnConstant.ATTRGROUP_ID, dto.getAttrgroupId());
        return this.attrAttrgroupDao.delete(wrapper) > 0;
    }

}
